package com.yl.chainStore.services.impl.sick

import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper
import com.baomidou.mybatisplus.core.toolkit.Wrappers
import com.yl.chainStore.common.Constants
import com.yl.chainStore.common.enums.Status
import com.yl.chainStore.common.enums.TypeEnum
import com.yl.chainStore.entity.sick.CustomerSubscribeItem
import com.yl.chainStore.entity.sick.CustomerSubscribeLog
import com.yl.chainStore.entity.sick.SickMedicalRecords
import com.yl.chainStore.entity.sick.SickMedicalRecordsDetail
import com.yl.chainStore.entity.user.CompanyUserOperationLog
import com.yl.chainStore.entity.user.CompanyUserOperationLogDetail
import com.yl.chainStore.mapper.sick.CustomerSubscribeItemMapper
import com.yl.chainStore.mapper.sick.CustomerSubscribeLogMapper
import com.yl.chainStore.mapper.sick.SickMedicalRecordsDetailMapper
import com.yl.chainStore.mapper.user.CompanyUserOperationLogDetailMapper
import com.yl.chainStore.mapper.user.CompanyUserOperationLogMapper
import com.yl.chainStore.pojo.vo.sick.CustomerSubscribeLogOperationVo
import com.yl.chainStore.pojo.vo.user.CompanyUserOperationLogSelectVo
import com.yl.chainStore.services.ICompanyUserOperationLogService
import com.yl.chainStore.services.ICustomerInfoService
import com.yl.chainStore.services.sick.ICompanyUserMedicalHistoryModelTypeService
import com.yl.chainStore.services.sick.ICustomerSubscribeLogService
import com.yl.chainStore.services.sick.ISickMedicalRecordsService
import com.yl.chainStore.util.dateFormat
import com.yl.chainStore.util.getDayAdd
import com.yl.chainStore.util.setTimeTo15Min
import com.yl.common.ErrorCode
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.common.getContext
import com.yl.message.common.MessageType
import com.yl.message.service.ISendMessageService
import com.yl.message.websocket.WebSocketMessageType
import com.yl.message.websocket.WebSocketMessageVo
import com.yl.users.services.ICompanyDeptService
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class CustomerSubscribeLogServiceImpl(
	private val customerSubscribeLogMapper: CustomerSubscribeLogMapper,
	private val customerSubscribeItemMapper: CustomerSubscribeItemMapper,
	private val sickMedicalRecordsDetailMapper: SickMedicalRecordsDetailMapper,
	private val companyUserOperationLogMapper: CompanyUserOperationLogMapper,
	private val companyUserOperationLogDetailMapper: CompanyUserOperationLogDetailMapper

) : ICustomerSubscribeLogService {

	@Autowired
	private lateinit var iCustomerInfoService: ICustomerInfoService

	@Autowired
	private lateinit var iSickMedicalRecordsService: ISickMedicalRecordsService

	@Autowired
	private lateinit var iCompanyDeptService: ICompanyDeptService

	@Autowired
	private lateinit var iSendMessageService: ISendMessageService

	@Autowired
	private lateinit var iCompanyUserOperationLogService: ICompanyUserOperationLogService

	companion object {
		private val log = LoggerFactory.getLogger(ICompanyUserMedicalHistoryModelTypeService::class.java)
	}

	override fun getById(id: Long): CustomerSubscribeLog? {
		val selectById = customerSubscribeLogMapper.selectById(id)
		if (selectById != null) {
			iCustomerInfoService.getJoinInfoByCustomerId(selectById.customerId,selectById)
		}
		return selectById
	}

	override fun updateInfo(subscribeLog: CustomerSubscribeLog): ResponseBody {
		val byId = getById(subscribeLog.id) ?: return returnError(
			ErrorCode.DATA_IS_NOT_FIND,
			"未找到预约信息，请刷新重试"
		)
		val oldLog = byId.copy()
		setTimeTo15Min(subscribeLog.subscribeTime)
		val beforeTime = byId.subscribeTime
		val beforeStatus = byId.status
		val beforeSubscribeType = byId.subscribeType

		val updateWrapper = UpdateWrapper<CustomerSubscribeLog>()
		updateWrapper.eq("id",subscribeLog.id)
			.set("clinic_type",subscribeLog.clinicType)
			.set("subscribe_type",subscribeLog.subscribeType)
			.set("subscribe_time",subscribeLog.subscribeTime)
			.set("time_length",subscribeLog.timeLength)
			.set("consultant_id",subscribeLog.consultantId)
			.set("department_id",subscribeLog.departmentId)
			.set("doctor_id",subscribeLog.doctorId)
			.set("nurse_id",subscribeLog.nurseId)
			.set("remark",subscribeLog.remark)
			.set("item_ids",subscribeLog.itemIds)

		customerSubscribeLogMapper.update(null,updateWrapper)
		iCompanyUserOperationLogService.addLog(
			associatedId = oldLog.id,
			modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
			tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_SUBSCRIBE_LOG,
			updateType = TypeEnum.COMPANY_USER_OPERATION_LOG_UPDATE_TYPE_UPDATE,
			beforeObj = oldLog,
			afterObj = byId,
			customerId = oldLog.customerId,
			createUserId = getContext().userId
		)

		if (dateFormat(getDayAdd(Date(), 1)) == dateFormat(subscribeLog.subscribeTime)
			|| dateFormat(getDayAdd(Date(), 1)) == dateFormat(beforeTime)
		) {
			//明日预约刷新
			val lastLoginHavePremUsers = iCompanyDeptService.getLastLoginHavePremUsers(
				getContext().subCompanyId,
				Constants.UserPermCode.TOMORROW_SUBSCRIBE
			)
			val tomorrwVo = WebSocketMessageVo(
				messageType = WebSocketMessageType.REFRESH_COUNT,
				data = Constants.CountRefresh.TOMORROW_SUBSCRIBE
			)
			for (u in lastLoginHavePremUsers) {
				iSendMessageService.sendMessageToCompanyUserHaveType(
					JSONObject(0),
					JSONObject.toJSON(tomorrwVo) as JSONObject,
					MessageType.WEBSOCKET,
					u.id
				)
			}
		}
		if (beforeStatus == Status.CANCEL || byId.status == Status.CANCEL) {
			//取消预约刷新
			val lastLoginHavePremUsers = iCompanyDeptService.getLastLoginHavePremUsers(
				getContext().subCompanyId,
				Constants.UserPermCode.CANCEL_SUBSCRIBE
			)
			//取消预约刷新
			val cancelVo = WebSocketMessageVo(
				messageType = WebSocketMessageType.REFRESH_COUNT,
				data = Constants.CountRefresh.CANCEL_SUBSCRIBE
			)
			for (u in lastLoginHavePremUsers) {
				iSendMessageService.sendMessageToCompanyUserHaveType(
					JSONObject(0),
					JSONObject.toJSON(cancelVo) as JSONObject,
					MessageType.WEBSOCKET,
					u.id
				)
			}
		}
		if (beforeStatus == Status.CANCEL || beforeStatus == Status.CANCEL) {
			//明日预约刷新
			val lastLoginHavePremUsers = iCompanyDeptService.getLastLoginHavePremUsers(
				getContext().subCompanyId,
				Constants.UserPermCode.CANCEL_SUBSCRIBE
			)
			//取消预约刷新
			val cancelVo = WebSocketMessageVo(
				messageType = WebSocketMessageType.REFRESH_COUNT,
				data = Constants.CountRefresh.CANCEL_SUBSCRIBE
			)
			for (u in lastLoginHavePremUsers) {
				iSendMessageService.sendMessageToCompanyUserHaveType(
					JSONObject(0),
					JSONObject.toJSON(cancelVo) as JSONObject,
					MessageType.WEBSOCKET,
					u.id
				)
			}
		}
		if (beforeSubscribeType == TypeEnum.CUSTOMER_SUBSCRIBE_TYPE_UNDETERMINDED
			|| byId.subscribeType == TypeEnum.CUSTOMER_SUBSCRIBE_TYPE_UNDETERMINDED
		) {
			val lastLoginHavePremUsers = iCompanyDeptService.getLastLoginHavePremUsers(
				getContext().subCompanyId,
				Constants.UserPermCode.UNDETERMINED_SUBSCRIBE
			)
			//取消预约刷新
			val undeterminedVo = WebSocketMessageVo(
				messageType = WebSocketMessageType.REFRESH_COUNT,
				data = Constants.CountRefresh.UNDETERMINED_SUBSCRIBE
			)
			for (u in lastLoginHavePremUsers) {
				iSendMessageService.sendMessageToCompanyUserHaveType(
					JSONObject(0),
					JSONObject.toJSON(undeterminedVo) as JSONObject,
					MessageType.WEBSOCKET,
					u.id
				)
			}
		}
		return returnSuccess()
	}

	override fun updateByRecordDetail(recordDetail: SickMedicalRecordsDetail): ResponseBody {
		if(recordDetail.subscribeLogId == null){
			return returnSuccess()
		}
		val selectById = customerSubscribeLogMapper.selectById(recordDetail.subscribeLogId)
		selectById.clinicType = recordDetail.detailType
		selectById.subscribeTime = recordDetail.startTime
		selectById.consultantId = recordDetail.secondaryUserId
		selectById.doctorId = recordDetail.masterUserId
		setTimeTo15Min(selectById.subscribeTime)
		updateInfo(selectById)
		return returnSuccess()
	}

	override fun getSubscribeItemsByIds(ids: List<Long>): List<CustomerSubscribeItem> {
		log.info("预约管理 ==> 获取预约项目ids：{} ", ids)
		return customerSubscribeItemMapper.selectBatchIds(ids)
	}

	override fun getSubscribeItemsByIdsStr(ids: List<Long>): String {
		log.info("预约管理 ==> 获取预约项目字符串格式 ids：{} ", ids)
		if (ids.isNullOrEmpty()) {
			return ""
		}
		val items = getSubscribeItemsByIds(ids)
		val res = StringBuffer()
		for (item in items) {
			res.append(item.itemName + " ")
		}
		return res.toString()
	}

	override fun completeLog(vo: CustomerSubscribeLogOperationVo): ResponseBody {
		log.info("预约管理 ==> 完成预约 vo：{} ", vo)
		val customerSubscribeLog = customerSubscribeLogMapper.selectById(vo.id) ?: return returnError(
			ErrorCode.DATA_IS_NOT_FIND,
			"未找到预约，请刷新重试"
		)
		val oldLog = customerSubscribeLog.copy()
		if (customerSubscribeLog.status != Status.NEW_ADD &&
			customerSubscribeLog.status != Status.CANCEL
		) {
			return returnError(ErrorCode.OPERATION_DATA_ERROR, "该预约已被处理")
		}
		customerSubscribeLog.status = Status.COMPLETE
		customerSubscribeLogMapper.updateById(customerSubscribeLog)

		iCompanyUserOperationLogService.addLog(
			associatedId = oldLog.id,
			modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
			tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_SUBSCRIBE_LOG,
			updateType = TypeEnum.COMPANY_USER_OPERATION_LOG_UPDATE_TYPE_UPDATE,
			beforeObj = oldLog,
			afterObj = customerSubscribeLog,
			customerId = oldLog.customerId,
			createUserId = getContext().userId
		)
		return returnSuccess()
	}

	override fun cancelLog(vo: CustomerSubscribeLogOperationVo): ResponseBody {
		log.info("预约管理 ==> 取消预约 vo：{} ", vo)
		val customerSubscribeLog = customerSubscribeLogMapper.selectById(vo.id) ?: return returnError(
			ErrorCode.DATA_IS_NOT_FIND,
			"未找到预约，请刷新重试"
		)
		val oldLog = customerSubscribeLog.copy()
//		if (customerSubscribeLog.status != Status.NEW_ADD) {
//			val detail = getRecordsDetailBySubscribeId(vo.id)
//			if (detail != null) {
//				val delDetail = iSickMedicalRecordsService.delDetail(detail)
//				if (delDetail.bodyIsError()) {
//					return returnError(ErrorCode.OPERATION_DATA_ERROR, "该预约已被处理")
//				}
//			}
//		}
		customerSubscribeLog.status = Status.CANCEL
		customerSubscribeLog.cancelTime = Date()
		customerSubscribeLogMapper.updateById(customerSubscribeLog)
		iCompanyUserOperationLogService.addLog(
			associatedId = oldLog.id,
			modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
			tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_SUBSCRIBE_LOG,
			updateType = TypeEnum.COMPANY_USER_OPERATION_LOG_UPDATE_TYPE_UPDATE,
			beforeObj = oldLog,
			afterObj = customerSubscribeLog,
			customerId = oldLog.customerId,
			createUserId = getContext().userId
		)
		//通知前端刷新侧边栏
		val lastLoginHavePremUsers = iCompanyDeptService.getLastLoginHavePremUsers(
			getContext().subCompanyId,
			Constants.UserPermCode.CANCEL_SUBSCRIBE
		)
		val webSocketMessageVo = WebSocketMessageVo(
			messageType = WebSocketMessageType.REFRESH_COUNT,
			data = Constants.CountRefresh.CANCEL_SUBSCRIBE
		)
		for (u in lastLoginHavePremUsers) {
			iSendMessageService.sendMessageToCompanyUserHaveType(
				JSONObject(0),
				JSONObject.toJSON(webSocketMessageVo) as JSONObject,
				MessageType.WEBSOCKET,
				u.id
			)
		}

		return returnSuccess()
	}

	override fun backToNewAdd(id: Long): ResponseBody {
		val customerSubscribeLog = customerSubscribeLogMapper.selectById(id) ?: return returnError(
			ErrorCode.DATA_IS_NOT_FIND,
			"未找到预约，请刷新重试"
		)
		val oldLog = customerSubscribeLog.copy()
		customerSubscribeLog.status = Status.NEW_ADD
		customerSubscribeLogMapper.updateById(customerSubscribeLog)

		iCompanyUserOperationLogService.addLog(
			associatedId = oldLog.id,
			modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
			tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_SUBSCRIBE_LOG,
			updateType = TypeEnum.COMPANY_USER_OPERATION_LOG_UPDATE_TYPE_UPDATE,
			beforeObj = oldLog,
			afterObj = customerSubscribeLog,
			customerId = oldLog.customerId,
			createUserId = getContext().userId
		)
		return returnSuccess()
	}

	override fun subLogToRecordsDetail(id: Long): ResponseBody {
		val subscribeLog = customerSubscribeLogMapper.selectById(id)
			?: return returnError(ErrorCode.DATA_IS_NOT_FIND, "未找到预约，请刷新重试")
		return subLogToRecordsDetail(subscribeLog)
	}

	override fun subLogToRecordsDetail(subscribeLog: CustomerSubscribeLog): ResponseBody {
		if (getRecordsDetailBySubscribeId(subscribeLog.id) != null) {
			return returnError(ErrorCode.OPERATION_DATA_ERROR, "预约已被确认")
		}
		val detail = SickMedicalRecordsDetail(
			startTime = subscribeLog.subscribeTime,
			toDay = subscribeLog.subscribeTime,
			secondaryUserId = subscribeLog.consultantId,
			masterUserId = subscribeLog.doctorId,
			deptId = subscribeLog.subCompanyId,
			subscribeLogId = subscribeLog.id,
			customerId = subscribeLog.customerId,
			recordId = 0L,
			remark = subscribeLog.remark,
		)
		if (subscribeLog.itemIdsShow != null && subscribeLog.itemIdsShow!!.isNotEmpty()) {
			detail.content = getSubscribeItemsByIdsStr(subscribeLog.itemIdsShow!!)
		}
		val onGoingRecord = iCustomerInfoService.getOnGoingRecord(subscribeLog.customerId)
		if (onGoingRecord.isNotEmpty()) {
			detail.detailType = TypeEnum.SICK_MEDICAL_RECORD_DETAIL_TYPE_AGAIN
			detail.recordId = onGoingRecord[0].id
		} else {
			//没有就诊记录，创建一个就诊记录，
			val record = SickMedicalRecords(
				customerId = subscribeLog.customerId,
				doctorId = subscribeLog.doctorId,
				status = Status.ONGOING,
				actionChief = detail.content
			)
			val createMedicalRecords = iCustomerInfoService.createMedicalRecords(record)
			if (createMedicalRecords.bodyIsError()) {
				return createMedicalRecords
			}
			detail.recordId = record.id
		}
		return iCustomerInfoService.addMedicalRecordDetail(detail)
	}

	override fun getRecordsDetailBySubscribeId(id: Long): SickMedicalRecordsDetail? {
		val list = sickMedicalRecordsDetailMapper.selectList(
			Wrappers.query<SickMedicalRecordsDetail?>()
				.eq("subscribe_log_id", id)
		)

		if (list == null || list.isEmpty()) {
			return null
		}
		return list[0]
	}

	override fun getSubscribeLogOperationLog(id: Long): List<CompanyUserOperationLog> {
		val selectLogList = companyUserOperationLogMapper.selectLogList(
			CompanyUserOperationLogSelectVo(
				associatedId = id,
				modelType = TypeEnum.COMPANY_USER_OPERATION_LOG_MODEL_TYPE_RECORD,
				tableType = TypeEnum.COMPANY_USER_OPERATION_LOG_TABLE_TYPE_SUBSCRIBE_LOG,
			)
		)
		for(opLog in selectLogList){
			opLog.details = companyUserOperationLogDetailMapper.selectList(
				Wrappers.query<CompanyUserOperationLogDetail?>().eq(
					"log_id",opLog.id
				)
			)
		}

		return selectLogList
	}
}
